package com.fuyao.cloud.common.data.datascope;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.fuyao.cloud.admin.api.feign.RemoteMenuService;
import com.fuyao.cloud.admin.api.vo.MenuVo;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;

/**
 * @author lyhil
 */
@Slf4j
@Aspect
public class InterceptSelectPage implements Serializable {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private RemoteMenuService remoteMenuService;

    @Around("@annotation(selectScope)")
    public Object around(JoinPoint point, PageSelectScope selectScope) throws Throwable {

        String permission = StrUtil.emptyToDefault(selectScope.value(),"");

        Object[] args = point.getArgs();
        ProceedingJoinPoint proceedingJoinPoint = (ProceedingJoinPoint) point;

        List<MenuVo> menuList = remoteMenuService.findMenuByPermission(permission).getData();
        if (CollUtil.isEmpty(menuList)) {
            log.trace(" menu permission match is not exists: {} ", permission);
            return proceedingJoinPoint.proceed(args);
        }
        Optional<MenuVo> optionalMenu = menuList.stream().min(Comparator.comparingLong(MenuVo::getMenuId));

        // 判断参数中是否带dataScope数据权限。
        if (isArgsDataScopeExists(args) && optionalMenu.isPresent()) {
            MenuVo menuVo = optionalMenu.get();
            for (int i = 0; i < args.length; i++) {
                if (args[i] instanceof DataScope) {
                    DataScope dataScope = new DataScope();
                    dataScope.setMenuDataScope(menuVo.getDataScope());
                    dataScope.put("dataScope", "");
                    args[i] = dataScope;
                }
            }
        }

        // 执行方法。
        return proceedingJoinPoint.proceed(args);
    }

    private Boolean isArgsDataScopeExists(Object[] args) {
        if (ArrayUtil.isEmpty(args)) {
            return Boolean.FALSE;
        }
        for (int i = 0; i < args.length; i++) {
            if (args[i] instanceof DataScope) {
                return Boolean.TRUE;
            }
        }
        return Boolean.FALSE;
    }

}
